package com.qf.mybatisplus.config.jwt;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.qf.mybatisplus.entity.AppInfo;
import com.qf.mybatisplus.exception.customException.BusinessErrorException;
import com.qf.mybatisplus.exception.exceptioConstance.BusinessMsgEnum;
import com.qf.mybatisplus.service.AppInfoService;
import com.qf.mybatisplus.utils.JwtHelper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;


/**
 * jwt 过滤器
 */
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {


    @Autowired
    private AppInfoService appInfoService;

    @Value("${ignored.urls}")
    private String ignoreUrls;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String servletPath = request.getServletPath();
//        boolean isIgnored = ignoreUrls.contains(servletPath);
//        // 特定接口忽略校验
//        if (isIgnored) {
//            return true;
//        }
        //获取请求头中令牌
        String token = request.getHeader("Authorization");


        if (StrUtil.isBlank(token)) {

            throw new BusinessErrorException(BusinessMsgEnum.NO_TOKEN);
//                throw new MalformedJwtException("未找到token");
        }


        Claims claims = JwtHelper.parseJWT(token, JwtHelper.JWT_SECRET);
        // IP  进行 ip 安全性效验
        String audience = claims.getAudience();
        // 账号
        String account = (String) claims.get("account");
        AppInfo appInfo = appInfoService.getById(account);
        if (appInfo == null) {
            log.error("验证token失败：未找到该app信息");
            throw new UsernameNotFoundException(account);
        }

        Date expiration = claims.getExpiration();
        int compare = DateUtil.compare(expiration, new Date());
        if (compare < 0) {
            throw new BusinessErrorException(BusinessMsgEnum.TOKEN_EXPIRED);
        }
        return true;

    }

    /**
     * 拦截处理程序的执行。在 HandlerAdapter 实际上调用处理程序之后调用，但在 DispatcherServlet 呈现视图之前调用
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("1");
    }

    /**
     * 请求处理完成后的回调，即渲染视图后。将在处理程序执行的任何结果上调用，从而允许进行适当的资源清理。
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
    }

    public void printErrorInfo(HttpServletRequest request) {
//        log.error("JwtInterceptor->>>ErrorInfo####requestUrl:{};ip:{};header:{}", request.getRequestURI(), IpUtils.getRealIP(request), ToolUtil.getHttpHeader(request));
    }
}
